# -*- coding: utf-8 -*-
# @Date     : 2021/1/27 14:55
# @Author   : xiaochuang.wu
# @File     : oss_utils.py

"""oss工具类， 实现了
    1. oss上文件的遍历
    2. 上传文件到oss
    3. 下载oss的文件
    4. 删除oss上的文件
    ...

    @@@ 线上使用请使用正确的oss配置 !!!
"""


import os, oss2
KEY = ""
SECRET = ""
END_POINT = "oss-cn-hzfinance.aliyuncs.com"
BUCKET_NAME = ""


class OssUtil(object):
    def __init__(self, key, secret, end_point, bucket_name=None):
        self.auth = oss2.Auth(key, secret)
        self.end_point = end_point
        self.bucket = None if not bucket_name else oss2.Bucket(self.auth, end_point, bucket_name)

    # 对资源进行签名，返回可访问的URL链接🔗
    def sing_url(self, method, file, expire, slash_safe=False):
        return self.bucket.sign_url(method, file, expire, slash_safe=slash_safe)

    @staticmethod
    def auto_complete_dir(dir):
        dir = f"{dir}/" if not dir.endswith("/") else dir
        return dir

    @staticmethod
    def result_success(result_obj):
        if result_obj.status == 200:
            return True
        return False

    def get_oss_bucket(self, bucket_name):
        return oss2.Bucket(self.auth, self.end_point, bucket_name)

    def get_all_buckets(self):
        """获取所有存储空间"""
        service = oss2.Service(self.auth, self.end_point)
        return [b.name for b in oss2.BucketIterator(service)]

    def exists_file(self, file):
        exist = self.bucket.object_exists(file)
        print(exist)

    def get_file_list(self, oss_dir, bucket=None):
        """遍历当前文件夹下所有文件及目录(不递归遍历子目录)"""
        if not oss_dir.endswith("/"):
            oss_dir += '/'
        return [obj.key for obj in oss2.ObjectIteratorV2(bucket or self.bucket, prefix=oss_dir, delimiter='/')]

    def upload_file_to_oss(self, oss_dir, local_file, bucket=None):
        if not os.path.isfile(local_file):
            return False
        tmp_bucket = bucket or self.bucket
        local_dir, file_name = os.path.split(local_file)
        oss_file = os.path.join(oss_dir, file_name)
        result = tmp_bucket.put_object_from_file(oss_file, local_file)
        return self.result_success(result)

    def download_file_from_oss(self, oss_file, local_dir, bucket=None):
        if not os.path.isdir(local_dir):
            return False
        tmp_bucket = bucket or self.bucket
        _d, _f = os.path.split(oss_file)
        tmp_bucket.get_object_to_file(oss_file, os.path.join(local_dir, _f))

    # 只下载目录下的文件,子目录和子目录下文件不会被
    def download_file_from_oss_dir(self, oss_dir, local_dir):
        if not os.path.isdir(local_dir):
            return False
        oss_dir = self.auto_complete_dir(oss_dir)
        for obj in oss2.ObjectIteratorV2(self.bucket, prefix=oss_dir, delimiter='/'):
            if obj.is_prefix():
                continue
            _d, _f = os.path.split(obj.key)
            self.bucket.get_object_to_file(obj.key, os.path.join(local_dir, _f))

    def delete_oss_file(self, oss_file, bucket=None):
        tmp_bucket = bucket or self.bucket
        result = tmp_bucket.delete_object(oss_file)
        # result.status == 204 不是200，不确定是不是只有这一个状态码表示删除成功
        return True

    def delete_oss_dir_file(self, oss_dir):
        # 文件
        if self.exists_file(oss_dir):
            ret = self.delete_oss_file(oss_dir)
            print(f"delete: {ret} ==> file: {oss_dir}")
            return

        # 目录
        oss_dir = self.auto_complete_dir(oss_dir)
        for obj in oss2.ObjectIteratorV2(self.bucket, prefix=oss_dir, delimiter='/'):
            if obj.is_prefix():
                self.delete_oss_dir_file(obj.key)
                continue

            ret = self.delete_oss_file(obj.key)
            print(f"delete: {ret} ==> file: {obj.key}")


if __name__ == '__main__':
    obj = OssUtil(KEY, SECRET, END_POINT, BUCKET_NAME)
    # print(obj.get_all_buckets())

    # 获取oss目录wxc_test下文件[夹]列表
    print(obj.get_file_list('wxc_test'))

    # obj.exists_file('yalong-frame/172.18.161.249/ch10/20210322/20210322_131004.jpg')

    # 上传文件到oss上(指定oss目录和文件全路径)
    # print(obj.upload_file_to_oss("wxc_test/d1/c2", "/Users/xiaochuang.wu/juliang/project/yalongai/config.conf"))

    # 下载文件(指定oss上文件全路径和本地保存文件的目录)
    print(obj.download_file_from_oss("wxc_test/SaveVideo.log", "/Users/xiaochuang.wu/juliang/project/yalongai/logs"))
    # print(obj.download_file_from_oss("wxc_test/nvr_config.json", "/Users/xiaochuang.wu/juliang/project/yalongai/logs"))
    # print(obj.download_file_from_oss("yalong-result/172.18.161.249/ch12/latest.json", "/Users/xiaochuang.wu/juliang/project/yalongai/logs"))
    # print(obj.download_file_from_oss("yalong-result/172.18.161.249/ch10/20210228/20210228_101815.avi", "/Users/xiaochuang.wu/juliang/project/yalongai/logs"))
    # obj.sing_url('GET', 'yalong-result/172.18.161.249/ch12/latest.json', 3600)
    # obj.sing_url('GET', 'yalong-result/172.18.161.249/ch10/20210228/20210228_101815.avi', 3600)
    # 批量下载文件
    # obj.download_file_from_oss_dir("wxc_test", "/Users/xiaochuang.wu/juliang/project/yalongai/logs")

    # 删除oss文件(指定oss上文件全路径)
    # print(obj.delete_oss_file("wxc_test/config.conf"))

    # 批量删除oss文件
    # obj.delete_oss_dir_file("wxc_test")
